package cc.aiee.chinapay.core.tool;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import com.chinapay.secss.SecssConstants;
import com.chinapay.secss.SecssUtil;

import cc.aiee.chinapay.config.ChinaPayConfig;
import cc.aiee.chinapay.core.constants.ChinaPayConst;
import cc.aiee.chinapay.core.kit.ChinaPayKit;
import cc.aiee.core.bean.R;
import cc.aiee.core.kit.KitBean;
import cc.aiee.core.kit.KitMap;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;

public class ChinaPayTool {

	/**
	 * 同步应答需要encoding的交易类型.
	 */
	private static Set<String> encodingTransTypes = new HashSet<String>();

	static {
		encodingTransTypes.add("0004");
		encodingTransTypes.add("0504");
		encodingTransTypes.add("0505");
		encodingTransTypes.add("0606");
		encodingTransTypes.add("0608");
		encodingTransTypes.add("9904");
		encodingTransTypes.add("9905");

		encodingTransTypes.add("0006");
		encodingTransTypes.add("0505");
		encodingTransTypes.add("0601");
		encodingTransTypes.add("0607");
		encodingTransTypes.add("9901");
	}

	public static R<Map<String, String>> pack(Object object, ChinaPayConfig config) {
		// 风控保留域 RiskData TODO
		// 交易保留域 TranReserved TODO
		// 卡片保留域 CardTranData TODO
		SecssUtil secssUtil = new SecssUtil();
		secssUtil.init(ChinaPayKit.getProperties(config));
//		try {
//		String ppsPath = "E:\\amazing\\workspace\\sts\\20200721\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp1\\wtpwebapps\\CP_PAY_DEMO\\/WEB-INF/classes/000092009088965.properties";
//		Properties p = new Properties();
//		InputStream inStream = new FileInputStream(ppsPath);
//		p.load(inStream);
//		secssUtil.init(p);
//		Properties properties = ChinaPayKit.getProperties(config);
//		secssUtil.init(properties);
//	} catch (IOException e) {
//		e.printStackTrace();
//	}
		Map<String, String> sendMap = KitBean.beanToTreeMap(object, false, true);

		// TODO 将 风控保留域,交易保留域,卡片保留域 进行json封装
		secssUtil.sign(sendMap);// 签名

		if (!SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
			return new R<>(secssUtil.getErrCode(), secssUtil.getErrMsg(), false);
		}
		sendMap.put(ChinaPayConst.SIGNATURE, secssUtil.getSign());

		return new R<>(secssUtil.getErrCode(), secssUtil.getErrMsg(), true, sendMap);
	}

	/**
	 * 解析同步请求的应答内容
	 * 
	 * @param responseStr
	 * @param tranType
	 * @return
	 * @author YangLong <br>
	 *         2020-09-29 11:45:33
	 */
	public static Map<String, String> unSendSyncResponseStr(String responseStr, String tranType) {
		boolean isDecode = encodingTransTypes.contains(tranType);
		Map<String, String> map = KitMap.toMap(responseStr, isDecode ? CharsetUtil.UTF_8 : null);
		return map;
	}

	/**
	 * 解包异步通知请求
	 * 
	 * @param request
	 * @return
	 * @author YangLong <br>
	 *         2020-09-29 11:55:33
	 */
	public static R<Map<String, String>> unNotify(HttpServletRequest request) {
		Map<String, String> resultMap = new TreeMap<String, String>();
		Enumeration<String> paraNames = request.getParameterNames();
		try {
			while (paraNames.hasMoreElements()) {
				String key = paraNames.nextElement();
				// 跳过自定义字段
				if (key.startsWith(ChinaPayConst.SPEC_PRIFEX)) {
					continue;
				}
				// 跳过空字段
				String value = request.getParameter(key);
				if (StrUtil.isEmpty(value)) {
					continue;
				}
				value = URLDecoder.decode(value, CharsetUtil.UTF_8);
				resultMap.put(key, value);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return new R<>("-1", "使用UTF-8解码失败", false);
		}
		return new R<>("0", "success", true, resultMap);
	}

	/**
	 * 验证签名
	 * 
	 * @param secssUtil
	 * @param resultMap
	 * @return
	 * @author YangLong <br>
	 *         2020-09-29 11:50:08
	 */
	public static boolean verify(SecssUtil secssUtil, Map<String, String> resultMap) {
		secssUtil.verify(resultMap);
		return SecssConstants.SUCCESS.equals(secssUtil.getErrCode());
	}

	/**
	 * 解包
	 * 
	 * @param secssUtil
	 * @param resultMap
	 * @return
	 * @author YangLong <br>
	 *         2020-09-29 11:50:24
	 */
	public static R<Map<String, String>> unPack(SecssUtil secssUtil, Map<String, String> resultMap) {
		// 解码
		for (Map.Entry<String, String> entry : resultMap.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			if (StrUtil.isEmpty(value)) {
				continue;
			}
			// 解析卡保留域
			if (ChinaPayConst.CARD_TRAN_DATA.equals(key)) {
				secssUtil.decryptData(value);
				if (!SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
					return new R<>(secssUtil.getErrCode(), secssUtil.getErrMsg(), false);
				}
				// value = new String(Base64.decodeBase64(value),
				// Constants.ENCODING);
				value = secssUtil.getDecValue();
				resultMap.put(key, value);
			}
			if (ChinaPayConst.RISK_DATA.equals(key)) {
				secssUtil.decryptData(value);
				if (!SecssConstants.SUCCESS.equals(secssUtil.getErrCode())) {
					return new R<>(secssUtil.getErrCode(), secssUtil.getErrMsg(), false);
				}
				value = secssUtil.getDecValue();
				resultMap.put(key, value);
			}
		}
		return new R<>(secssUtil.getErrCode(), secssUtil.getErrMsg(), true, resultMap);
	}

	public static String getTranDate(Date now) {
		return DateUtil.format(now, DatePattern.PURE_DATE_PATTERN);
	}

	public static String getTranTime(Date now) {
		return DateUtil.format(now, DatePattern.PURE_TIME_PATTERN);
	}

	/**
	 * 如果收到商户服务 器返回的 http 200 应答码，就认为是通知商户成功，否则当天会再次通知，当天再 次通知最多 10 次。
	 * 
	 * @return
	 */
	public static String notifyReturn() {
		return "SUCCESS";
	}
}
